﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using DirectShowLib.DES;
using DirectShowLib;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using WMPLib;
using System.Threading;

namespace Thumbnail
{
    public class Video
    {
        protected string _filename = string.Empty;
        protected IMediaDet _mediadet = null;
        protected VideoInfoHeader _videoInfoHeader = null;

        public float AspectRatio
        {
            get { return _videoInfoHeader != null ? (float)_videoInfoHeader.BmiHeader.Width / _videoInfoHeader.BmiHeader.Height : 1.0f; }
        }

        public int Width
        {
            get { return _videoInfoHeader != null ? _videoInfoHeader.BmiHeader.Width : 0; }
        }

        public int Height
        {
            get { return _videoInfoHeader != null ? _videoInfoHeader.BmiHeader.Height : 0; }
        }

        public string Title
        {
            get { return Path.GetFileNameWithoutExtension(_filename); }
        }

        public Video(string filename)
        {
            if (File.Exists(filename))
            {
                _filename = filename;
                _mediadet = (IMediaDet)new MediaDet();

                _mediadet.put_Filename(filename);
                _mediadet.put_CurrentStream(0);

                Guid guidMediatype = Guid.Empty;
                _mediadet.get_StreamType(out guidMediatype);

                //if (guidMediatype == MediaType.Video)
                {
                    AMMediaType mediatype = new AMMediaType();
                    _mediadet.get_StreamMediaType(mediatype);
                    _videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(mediatype.formatPtr, typeof(VideoInfoHeader));
                    DsUtils.FreeAMMediaType(mediatype);
                }
            }
        }

        public Bitmap GetBitmap(double seconds, int width, int height)
        {
            // create a buffer to hold the image data from the MediaDet
            int bufferSize;
            _mediadet.GetBitmapBits(seconds, out bufferSize, IntPtr.Zero, width, height);
            IntPtr bufferPtr = Marshal.AllocHGlobal(bufferSize);
            _mediadet.GetBitmapBits(seconds, out bufferSize, bufferPtr, width, height);

            Bitmap bitmap = null;

            // compose a bitmap from the data in the managed buffer    
            unsafe
            {
                bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                BitmapData imageData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                int* imagePtr = (int*)imageData.Scan0;

                int bitmapHeaderSize = Marshal.SizeOf(_videoInfoHeader.BmiHeader);
                int* sourcePtr = (int*)((byte*)bufferPtr.ToPointer() + bitmapHeaderSize);

                for (int i = 0; i < (bufferSize - bitmapHeaderSize) / 4; i++)
                {
                    *imagePtr = *sourcePtr;
                    imagePtr++;
                    sourcePtr++;
                }

                bitmap.UnlockBits(imageData);
                // DirectShow stores pixels in a different order than Bitmaps do
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);
            }

            Marshal.FreeHGlobal(bufferPtr);

            return bitmap;
        }
    }

    public class VideoProperties
    {
        public int Width { get; set; }
        public int Height { get; set; }
        public long Duration { get; set; }

        public VideoProperties(string fileName)
        {
            WindowsMediaPlayerClass wmp = new WindowsMediaPlayerClass();
            IWMPMedia mediaInfo = wmp.newMedia(fileName);
            wmp.currentMedia = mediaInfo;
            Thread.Sleep(1000);

            Width = mediaInfo.imageSourceWidth;
            Height = mediaInfo.imageSourceHeight;
            wmp.stop();

            Duration = (long)mediaInfo.duration;

            wmp.close();
        }
    }
}
